#!/bin/bash
ZONE=--zone=public
PERM=--permanent
 
Firewall (){
        systemctl status firewalld.service 1>/dev/null 2>&1
        B=$?
        if [ $B -eq 4 ]; then
                echo $server no firewalld.service
        else
                if [ $B -ne 0 ]; then
                        echo "$server 当前防火墙属于关闭状态：(1)start (2)stop"
                        read -p "你的选择：" choice
                        case $choice in
                        1)
                                systemctl start  firewalld 1>/dev/null 2>&1
                                systemctl enable firewalld 1>/dev/null 2>&1
                                echo $server 防火墙开启中
								Firewall;;
                       	2)
                                echo $server 未开启防火墙，退出程序;;
                        esac
                else
						startall
                fi
        fi
}
startall (){
    until
    clear
    input=
	echo "$(basename $0)正在执行...本脚本完成防火墙相关配置"
    echo "请输入对应选项，选择要执行的操作"
	echo ""
	echo "当前防火墙规则:"
        firewall-cmd --zone=public --list-all
	echo ""
    echo "" 
    echo "(1)开放、关闭端口"
    echo "(2)添加、开放、移除IP地址规则"
    echo "输入后不需要按回车/如果需要按回车进入删除下面的-n1"
    echo ""
    echo "                                q.退出"
    echo ""
    read -p "请输入您的选择：" -n1 input
    if [ "$input"q = q ];then startall;fi
    test $input = q
    do
    	case $input in
    	1)echo
    		port
        	;;
    	2)echo
    		ip
        	;;
    	esac
    done
    echo ""
}
port (){
    clear
    input=
	echo "当前防火墙规则:"
	firewall-cmd --zone=public --list-all
	echo ""
	echo "****************"
	echo "输入要修改的端口"
	echo "e.g. 5080"
	echo "e.g. 5050 5080"
	echo "e.g. 80 5050-5060 5080"
	echo -n "ports:"
	read PORTS
	echo "*************"
	echo "选择协议"
	echo "e.g (1)tcp/(2)udp/(3)all, 默认：tcp."
	echo -n "protocol:"
	read PROTOCOL
	echo "**********************"
	echo "选择添加/删除规则"
	echo "e.g (1)add/(2)remove, 默认：add."
	echo -n "action:"
	read ACTION
	case $PROTOCOL in
		3)
    		PROTOCOL="all"
    		;;
		2)
    		PROTOCOL="udp"
    		;;
		1|*)
			PROTOCOL="tcp"
	esac
 
	case $ACTION in
		2)
    		ACTION="remove"
			;;
		1|*)
			ACTION="add"
			;;
	esac
	for PORT in $PORTS
	do
        # case when range ports given like '5050-5060'
        if [ $(expr index "-" $PORT) ];then
                START_PORT=${PORT%-*}
                END_PORT=${PORT#*-}
                while [ $START_PORT -le $END_PORT ]
                do
                        do_port_with_protocol $START_PORT $PROTOCOL
                        let START_PORT++
                done
                continue
        fi
        # normal case like '5080'
        do_port_with_protocol $START_PORT $PROTOCOL
	done
	firewall-cmd --reload
}
do_port_with_protocol() {
  case $2 in
    "tcp"|"udp")
      echo "firewall-cmd $ZONE $PERM --$ACTION-port=$1/$2"
      firewall-cmd $ZONE $PERM --$ACTION-port=$1/$2
      ;;
    "all")
      echo "firewall-cmd $ZONE $PERM --$ACTION-port=$1/tcp"
      firewall-cmd $ZONE $PERM --$ACTION-port=$1/tcp
      echo "firewall-cmd $ZONE $PERM --$ACTION-port=$1/udp"
      firewall-cmd $ZONE $PERM --$ACTION-port=$1/udp
      ;;
    *)
      echo "Error protocol $2 when $ACTION port $1"
  esac
}
 
Ip (){
    clear
    input=
	echo "当前防火墙规则:"
        firewall-cmd --zone=public --list-all
	echo ""
	echo "**************"
	echo "输入要修改的IP"
    echo "e.g. 192.168.0.66"
    echo "e.g. 192.168.0.0/24"
    echo "e.g. 192.168.0.66 10.152.3.161"
    echo -n "IP:"
    read IP
	echo "****************"
	echo "输入要修改的端口"
	echo "e.g. 5080"
	echo "e.g. 5050 5080"
	echo "e.g. 80 5050-5060 5080"
	echo -n "ports:"
	read PORTS
	echo "************"
	echo "选择协议:"
	echo "e.g (1)tcp/(2)udp/(3)all, default tcp."
	echo -n "protocol:"
	read PROTOCOL
 
	case $PROTOCOL in
		3)
        	PROTOCOL="all"
        	;;
		2)
        	PROTOCOL="udp"
        	;;
		1|*)
			PROTOCOL="tcp"	
	esac
 
	for PORT in $PORTS
	do
        # normal case like '37006'
        do_ip_with_protocol $PORT $PROTOCOL
	done
}
do_ip_with_protocol() {
	for i in $IP
	do
	case $2 in
    		"tcp"|"udp")
			echo "firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$i" port port="$1" protocol="$2" $switch""
				firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$i" port port="$1" protocol="$2" $switch"
      		;;
    		"all")
			echo "firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$i" port port="$1" protocol="tcp" $switch""
                firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$i" port port="$1" protocol="tcp" $switch"
			echo "firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$i" port port="$1" protocol="udp" $switch""
                firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$i" port port="$1" protocol="udp" $switch"
      		;;
    		*)
      		echo "Error protocol $2 when $ACTION port $1"
 	esac
	done
}
ip (){
        until
        clear
        input=
		echo "当前防火墙规则:"
        firewall-cmd --zone=public --list-all
		echo ""
		echo "*********************************"
        echo "请输入对应选项，选择要执行的操作:"
        echo "" 
        echo "(1)设置开放的IP地址规则"
		echo "(2)设置限制的IP地址规则"
		echo "(3)设置移除的IP地址规则"
        echo ""
        echo ""
        echo "                           q.返回上一层"
        echo ""
        read -p "请输入您的选择：" -n1 input
        if [ "$input"q = q ];then port;fi
        test $input = q
        do
        case $input in
        1)echo
				ACTION="add"
				switch="accept"
				Ip
                ;;
		2)echo  
                ACTION="add"
                switch="reject"
                Ip
                ;;
		3)echo  
				clear
				echo "`firewall-cmd --zone=public --list-rich-rules`"|awk -F ':' '{print NR":"$0}'
				echo -n "请输入你要删除的防火墙规则行号:"
	    		read NUM
        		ACTION="remove"
        		for num in $NUM
        		do
					IP=`firewall-cmd --zone=public --list-rich-rules|awk "NR== $num"|awk -F "\"" '{print $4}'`
					PORTS=`firewall-cmd --zone=public --list-rich-rules|awk "NR== $num"|awk -F "\"" '{print $6}'`
					PROTOCOL=`firewall-cmd --zone=public --list-rich-rules|awk "NR== $num"|awk -F "\"" '{print $8}'`
					switch=`firewall-cmd --zone=public --list-rich-rules|awk "NR== $num"|awk -F "\"" '{print $9}'`
					firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$IP" port port="$PORTS" protocol="$PROTOCOL" $switch"
					echo "firewall-cmd $PERM $ZONE --$ACTION-rich-rule="rule family="ipv4" source address="$IP" port port="$PORTS" protocol="$PROTOCOL" $switch""
				done
 
        esac
		firewall-cmd --reload
        done
}
Firewall